package com.elitetyc.eliteim.client;

import cn.hutool.json.JSONUtil;
import com.elitetyc.eliteim.client.handler.MsgSuccessHandler;
import com.elitetyc.eliteim.common.constant.Constants;
import com.elitetyc.eliteim.common.model.impl.UserLoginData;
import com.elitetyc.eliteim.common.proto.RequestProto;
import com.elitetyc.eliteim.common.util.MsgUtil;
import com.elitetyc.eliteim.client.config.IMClientProperties;
import com.elitetyc.eliteim.client.config.IMServerInfo;
import com.elitetyc.eliteim.client.handler.ClientChannelInitializer;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author yuanchao.tan
 * @version 1.0
 * @description im客户端
 * @Date 2021/9/17 9:33
 */
@Component
@Slf4j
public class EliteIMClient {

    private final EventLoopGroup group = new NioEventLoopGroup(0,new DefaultThreadFactory("im-work"));

    @Autowired
    private List<MsgSuccessHandler> msgSuccessHandlers;

    @Autowired
    private IMServerInfo imServerInfo;

    @Autowired
    private ClientChannelInitializer clientChannelInitializer;

    public NioSocketChannel nioSocketChannel;


    @PostConstruct
    public void init(){
        startClient();
    }
    /**
     * 开启连接
     */
    private void startClient() {
        Bootstrap bootstrap = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(clientChannelInitializer);
        ChannelFuture future=null;
        try {
            future = bootstrap.connect(imServerInfo.ip(), imServerInfo.imPort()).sync();
            if (future.isSuccess()){
                nioSocketChannel = (NioSocketChannel) future.channel();
            }else throw new InterruptedException();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    /**
     * 当丢失连接时设置channel为空
     * @param channel
     */
    public void clearSocket(Channel channel) {
        if (channel==nioSocketChannel){
            this.nioSocketChannel.close();
            this.nioSocketChannel = null;
        }
    }


    /**
     * 重连
     */
    public void reconnect() {
        log.info("reconnect server start...");
        init();
        log.info("reconnect server end...");
    }

    public void sendMsg(RequestProto.RequestProtocol data){
        nioSocketChannel.writeAndFlush(data).addListener((ChannelFutureListener)future->{
            if (future.isSuccess()){
                // 如果成功，执行指定的消息回调处理器
                for (MsgSuccessHandler handler : msgSuccessHandlers) {
                    if (handler.isSupport(data)){
                        handler.handle(data);
                        break;
                    }
                }
            }
        });
    }
}
